import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文字体和显示选项
plt.rcParams['font.sans-serif'] = ['DejaVu Sans', 'Arial']
plt.rcParams['axes.unicode_minus'] = False
pd.set_option('display.max_columns', None)
# 数据加载与基本信息查看
df = pd.read_csv('1/MBA.csv')
print(f"数据集形状：{df.shape}")
print("\n前5行数据")
print(df.head())
print("\n数据类型")
print(df.dtypes)  
# 描述性统计分析
numeric_cols = ['gpa', 'gmat', 'work_exp']
categorical_cols = ['gender', 'international', 'major', 'race', 'work_industry', 'admission']
print("\n数值型变量统计")
print(df[numeric_cols].describe())
print("\n分类变量统计")
for col in categorical_cols:
    print(f"\n{col}:")
    print(df[col].value_counts())
# 缺失值处理
print("\n缺失值情况")
missing_info = df.isnull().sum()
print(missing_info[missing_info > 0])
df_processed = df.copy()
# 填充admission列缺失值为'Reject'
df_processed['admission'] = df_processed['admission'].fillna('Reject')
# 填充race列缺失值为众数
if df_processed['race'].isnull().sum() > 0:
    mode_race = df_processed['race'].mode()[0]
    df_processed['race'] = df_processed['race'].fillna(mode_race)
print("缺失值处理完成")
# 特征编码
print("\n特征编码")
df_encoded = df_processed.copy()
# 性别编码：Male=0, Female=1
gender_mapping = {'Male': 0, 'Female': 1}
df_encoded['gender'] = df_encoded['gender'].map(gender_mapping)
# 国际学生编码：False=0, True=1
df_encoded['international'] = df_encoded['international'].astype(int)
# OneHot编码其他分类变量
categorical_for_onehot = ['major', 'race', 'work_industry']
for col in categorical_for_onehot:
    dummies = pd.get_dummies(df_encoded[col], prefix=col)
    df_encoded = df_encoded.drop(col, axis=1)
    df_encoded = pd.concat([df_encoded, dummies], axis=1)
print(f"编码后数据形状：{df_encoded.shape}") 
# 数值特征标准化
print("\n数值特征标准化")
for col in numeric_cols:
    if col in df_encoded.columns:
        mean = df_encoded[col].mean()
        std = df_encoded[col].std()
        df_encoded[col + '_standardized'] = (df_encoded[col] - mean) / std
print("标准化完成")

# 数据可视化
print("\n绘制图表...")
# 数值变量分布图
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
fig.suptitle('Numeric Variables Distribution', fontsize=16)
for i, col in enumerate(numeric_cols):
    row = i // 2
    col_pos = i % 2
    axes[row, col_pos].hist(df_processed[col], bins=30, alpha=0.7, color='skyblue')
    axes[row, col_pos].set_title(f'{col} Distribution')
    axes[row, col_pos].set_xlabel(col)
    axes[row, col_pos].set_ylabel('Frequency')
axes[1, 1].remove()
plt.tight_layout()
plt.savefig('1/output/数值变量分布图.png', dpi=300, bbox_inches='tight')
plt.show()

# 分类变量分布图
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
fig.suptitle('Categorical Variables Distribution', fontsize=16)
for i, col in enumerate(categorical_cols):
    row = i // 3
    col_pos = i % 3
    value_counts = df_processed[col].value_counts()
    axes[row, col_pos].bar(range(len(value_counts)), value_counts.values, color='lightcoral')
    axes[row, col_pos].set_title(f'{col} Distribution')
    axes[row, col_pos].set_xticks(range(len(value_counts)))
    axes[row, col_pos].set_xticklabels(value_counts.index, rotation=45)
    axes[row, col_pos].set_ylabel('Frequency')
plt.tight_layout()
plt.savefig('1/output/分类变量分布图.png', dpi=300, bbox_inches='tight')
plt.show()

# 录取状态与数值变量关系图
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
fig.suptitle('Numeric Variables by Admission Status', fontsize=16)
for i, col in enumerate(numeric_cols):
    df_processed.boxplot(column=col, by='admission', ax=axes[i])
    axes[i].set_title(f'{col} vs Admission Status')
    axes[i].set_xlabel('Admission Status')
plt.tight_layout()
plt.savefig('1/output/录取状态与数值变量关系图.png', dpi=300, bbox_inches='tight')
plt.show()

# 相关性分析
print("\n相关性分析")
correlation_matrix = df_processed[numeric_cols].corr()
print(correlation_matrix)
# 相关性热力图
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0, square=True, fmt='.3f')
plt.title('Numeric Variables Correlation Heatmap')
plt.tight_layout()
plt.savefig('1/output/相关性热力图.png', dpi=300, bbox_inches='tight')
plt.show()

# 录取状态分析
print("\n录取状态分析")
admission_counts = df_processed['admission'].value_counts()
print(admission_counts)
admission_rate = admission_counts / admission_counts.sum() * 100
print("\n录取率")
for status, rate in admission_rate.items():
    print(f"{status}: {rate:.1f}%")

# 不同特征的录取率
print("\n按性别录取率")
print(pd.crosstab(df_processed['gender'], df_processed['admission'], normalize='index') * 100)
print("\n按国际学生身份录取率")
print(pd.crosstab(df_processed['international'], df_processed['admission'], normalize='index') * 100)
print("\n按专业录取率")
print(pd.crosstab(df_processed['major'], df_processed['admission'], normalize='index') * 100)
# 数值特征按录取状态统计
print("\n数值特征按录取状态统计")
for col in numeric_cols:
    print(f"\n{col}:")
    print(df_processed.groupby('admission')[col].describe())
# 保存处理后的数据
df_processed.to_csv('1/output/MBA_processed.csv', index=False)
df_encoded.to_csv('1/output/MBA_encoded.csv', index=False)
print("\n数据已保存完成")


